﻿using System;
using UnityEngine;
using UnityEngine.UI;

namespace UnityEngine.UnityVideoPlayer
{
    public class VideoPlayerView : MonoBehaviour
    {
        public UnityVideoPlayer VideoPlayer { get; protected set; }

        public event Action<int> OnFullScreenSwitch;
        public event Action<bool> OnPlayStateEvent;

        public Button fullButton;

        public Button resetButton;

        public Button startButton;

        public Button pauseButton;

        public Text timeLable;

        public Text maxTimeLable;

        public Slider slider;

        public ImageView imgView;

        public RectTransform videoUIRoot;

        private Button videoSwitch;

        public bool EnableVideoControl
        {
            get {
                return videoUIRoot.gameObject.activeSelf;
            }
            set {
                videoUIRoot.gameObject.SetActive(value);
            }
        }

        public bool EnableVideoSwitch
        {
            get
            {
                return videoSwitch.enabled;
            }
            set
            {
                videoSwitch.enabled = value;
            }
        }

        private void Start()
        {
            fullButton.onClick.AddListener(() => {
                EnterFull();
            });

            resetButton.onClick.AddListener(() => {
                ExitFull();
            });

            startButton.onClick.AddListener(OnStartButtonClick);

            pauseButton.onClick.AddListener(OnPauseButtonClick);

            slider.onValueChanged.AddListener(OnSliderValueChanged);

            videoSwitch = imgView.rawImage.GetComponent<Button>();

            videoSwitch.onClick.AddListener(()=> VideoPlayer.SwitchPause());

            EnableVideoControl = false;

            EnableVideoSwitch = false;

            HideUIRoot(false);
        }

        public void EnterFull()
        {
            fullButton.gameObject.SetActive(false);
            resetButton.gameObject.SetActive(true);

            OnFullScreenSwitch?.Invoke(1);
        }

        public void ExitFull()
        {
            resetButton.gameObject.SetActive(false);
            fullButton.gameObject.SetActive(true);

            OnFullScreenSwitch?.Invoke(0);
        }

        private void OnDestroy()
        {
            Clear();
        }

        private void OnPauseButtonClick()
        {
            VideoPlayer.SwitchPause();
        }

        private void OnStartButtonClick()
        {
            VideoPlayer.SwitchPause();
        }

        private void OnSliderValueChanged(float value)
        {
            if (VideoPlayer != null)
            {
                if (VideoPlayer.Duration < value)
                    return;

                VideoPlayer.Time = value;
            }
        }
  
        public void Clear()
        {
            if (VideoPlayer != null)
            {
                VideoPlayer.OnFrameReady -= VideoPlayer_OnFrameReady;

                VideoPlayer = null;
            }

            VideoPlayer = null;

            imgView.Tex = null;
        }

        public void Setup(UnityVideoPlayer videoPlayer, bool isFullScreen)
        {
            fullButton.gameObject.SetActive(!isFullScreen);

            resetButton.gameObject.SetActive(isFullScreen);

            if (VideoPlayer != null)
            {
                VideoPlayer.OnFrameReady -= VideoPlayer_OnFrameReady;
            }

            VideoPlayer = videoPlayer;
            
            VideoPlayer.OnFrameReady += VideoPlayer_OnFrameReady;

            imgView.Tex = VideoPlayer.TargetTexture;

            UpdatePlayingStates(VideoPlayer.IsPlaying);

            //Debug.Log($"Setup:  duration:{VideoPlayer.Duration}  isPlaying:{videoPlayer.IsPlaying}  isPrepared:{videoPlayer.IsPrepared}  clip:{videoPlayer.videoPlayer.clip}");

            UpdateMaxTime((float)VideoPlayer.Duration);

            UpdateSliders(VideoPlayer.Time);
        }

        private void VideoPlayer_OnFrameReady(long f)
        {
            UpdateMaxTime((float)VideoPlayer.Duration);

            UpdateSliders(VideoPlayer.Time);
        }

        private string ToTimeString(float time)
        {
            var s = (int)time;

            var m = s / 60;

            s %= 60;

            return string.Format("{0:D2}:{1:D2}", m, s);
        }
        
        public void UpdatePlayingStates(bool isPlaying)
        {
            startButton.gameObject.SetActive(!isPlaying);
            
            pauseButton.gameObject.SetActive(isPlaying);

            OnPlayStateEvent?.Invoke(isPlaying);
        }

        public void UpdateSliders(float time)
        {
            slider.SetValueWithoutNotify(time);

            timeLable.text = ToTimeString(time);
        }

        public void UpdateMaxTime(float maxTime)
        {
            if (maxTime == 0 || slider.maxValue == maxTime)
                return;
            
            maxTimeLable.text = ToTimeString(maxTime);

            //防止触发 OnSliderValueChanged
            slider.SetValueWithoutNotify(0);

            slider.maxValue = maxTime;

            slider.SetValueWithoutNotify(0);
        }

        private void Update()
        {
            if(VideoPlayer != null)
            {
                UpdatePlayingStates(VideoPlayer.IsPlaying);
            }

            if (Input.GetKeyDown(KeyCode.Space))
            {
                VideoPlayer?.SwitchPause();
            }

            if (Input.GetKeyDown(KeyCode.LeftArrow))
            {
                if(VideoPlayer != null && EnableVideoControl)
                    slider.value = (slider.value <= 5) ? 0 : slider.value - 5;
            }

            if (Input.GetKeyDown(KeyCode.RightArrow))
            {
                if (VideoPlayer != null && EnableVideoControl)
                    slider.value = (slider.maxValue - slider.value <= 5) ? slider.maxValue : slider.value + 5;
            }
        }

        public void AreaOver()
        {
            ShowUIRoot(true);
        }

        public void AreaLeave()
        {
            HideUIRoot(true);
        }

        public void ShowUIRoot(bool anim)
        {
            var cg = videoUIRoot.GetComponent<CanvasGroup>();

            //cg.DOKill();

            //if (anim)
            //    cg.DOFade(1.0f, 0.3f);
            //else
            //    cg.alpha = 1;
        }

        public void HideUIRoot(bool anim, float delay = 0)
        {
            var cg = videoUIRoot.GetComponent<CanvasGroup>();

            //cg.DOKill();

            //if (anim)
            //    cg.DOFade(0.0f, 0.3f).SetDelay(delay);
            //else
            //    cg.alpha = 0;
        }
    }
}
